#ifndef _WX_FILEDLGG_H_
#define _WX_FILEDLGG_H_

#include "wx/listctrl.h"
#include "wx/datetime.h"
#include "wx/filefn.h"
#include "wx/filedlg.h"

class wxBitmapButton;
class wxCheckBox;
class wxChoice;
class wxFileData;
class wxFileCtrl;
class wxGenericFileDialog;
class wxListEvent;
class wxListItem;
class wxStaticText;
class wxTextCtrl;

class wxGenericFileDialog: public wxFileDialogBase {
  public:
    wxGenericFileDialog() : wxFileDialogBase() { Init(); }
    wxGenericFileDialog( wxWindow *parent,
                         const wxString& message = wxFileSelectorPromptStr,
                         const wxString& defaultDir = wxEmptyString,
                         const wxString& defaultFile = wxEmptyString,
                         const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
                         long style = wxFD_DEFAULT_STYLE,
                         const wxPoint& pos = wxDefaultPosition,
                         const wxSize& sz = wxDefaultSize,
                         const wxString& name = wxFileDialogNameStr,
                         bool bypassGenericImpl = false );

    bool Create( wxWindow *parent,
                 const wxString& message = wxFileSelectorPromptStr,
                 const wxString& defaultDir = wxEmptyString,
                 const wxString& defaultFile = wxEmptyString,
                 const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
                 long style = wxFD_DEFAULT_STYLE,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& sz = wxDefaultSize,
                 const wxString& name = wxFileDialogNameStr,
                 bool bypassGenericImpl = false );

    virtual ~wxGenericFileDialog();
    virtual void SetMessage( const wxString& message ) { SetTitle( message ); }
    virtual void SetPath( const wxString& path );
    virtual void SetFilterIndex( int filterIndex );
    virtual void SetWildcard( const wxString& wildCard );
    virtual void GetPaths( wxArrayString& paths ) const;
    virtual void GetFilenames( wxArrayString& files ) const;
    virtual int ShowModal();
    virtual bool Show( bool show = true );
    void OnSelected( wxListEvent &event );
    void OnActivated( wxListEvent &event );
    void OnList( wxCommandEvent &event );
    void OnReport( wxCommandEvent &event );
    void OnUp( wxCommandEvent &event );
    void OnHome( wxCommandEvent &event );
    void OnListOk( wxCommandEvent &event );
    void OnNew( wxCommandEvent &event );
    void OnChoiceFilter( wxCommandEvent &event );
    void OnTextEnter( wxCommandEvent &event );
    void OnTextChange( wxCommandEvent &event );
    void OnCheck( wxCommandEvent &event );
    virtual void HandleAction( const wxString &fn );
    virtual void UpdateControls();
  private:
    bool m_bypassGenericImpl;
  protected:
    void DoSetFilterIndex( int filterindex );
    wxString       m_filterExtension;
    wxChoice      *m_choice;
    wxTextCtrl    *m_text;
    wxFileCtrl    *m_list;
    wxCheckBox    *m_check;
    wxStaticText  *m_static;
    wxBitmapButton *m_upDirButton;
    wxBitmapButton *m_newDirButton;
  private:
    void Init();
    DECLARE_DYNAMIC_CLASS( wxGenericFileDialog )
    DECLARE_EVENT_TABLE()
    static long ms_lastViewStyle;     // list or report?
    static bool ms_lastShowHidden;    // did we show hidden files?
};

#ifdef wxUSE_GENERIC_FILEDIALOG

class wxFileDialog: public wxGenericFileDialog {
  public:
    wxFileDialog() {}

    wxFileDialog( wxWindow *parent,
                  const wxString& message = wxFileSelectorPromptStr,
                  const wxString& defaultDir = wxEmptyString,
                  const wxString& defaultFile = wxEmptyString,
                  const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
                  long style = 0,
                  const wxPoint& pos = wxDefaultPosition )
      : wxGenericFileDialog( parent, message, defaultDir, defaultFile, wildCard, style, pos ) {
    }

  private:
    DECLARE_DYNAMIC_CLASS( wxFileDialog )
};

#endif // wxUSE_GENERIC_FILEDIALOG

class wxFileData {
  public:
    enum fileType {
      is_file  = 0x0000,
      is_dir   = 0x0001,
      is_link  = 0x0002,
      is_exe   = 0x0004,
      is_drive = 0x0008
    };

    wxFileData() { Init(); }
    wxFileData( const wxFileData& fileData ) { Copy( fileData ); }
    wxFileData( const wxString &filePath, const wxString &fileName,fileType type, int image_id );
    void Copy( const wxFileData &other );
    void ReadData();
    wxString GetFileName() const { return m_fileName; }
    wxString GetFilePath() const { return m_filePath; }
    void SetNewName( const wxString &filePath, const wxString &fileName );
    wxFileOffset GetSize() const { return m_size; }
    wxString GetFileType() const;
    wxDateTime GetDateTime() const { return m_dateTime; }
    wxString GetModificationTime() const;
    wxString GetPermissions() const { return m_permissions; }
    int GetImageId() const { return m_image; }

    bool IsFile() const  { return !IsDir() && !IsLink() && !IsDrive(); }
    bool IsDir() const   { return ( m_type & is_dir ) != 0; }
    bool IsLink() const  { return ( m_type & is_link ) != 0; }
    bool IsExe() const   { return ( m_type & is_exe ) != 0; }
    bool IsDrive() const { return ( m_type & is_drive ) != 0; }
    int GetType() const { return m_type; }
    enum fileListFieldType {
      FileList_Name,
      FileList_Size,
      FileList_Type,
      FileList_Time,
      FileList_Perm,
      FileList_Max
    };
    wxString GetEntry( fileListFieldType num ) const;
    wxString GetHint() const;
    void MakeItem( wxListItem &item );
    wxFileData& operator = ( const wxFileData& fd ) { Copy( fd ); return *this; }
  protected:
    wxString m_fileName;
    wxString   m_filePath;
    wxFileOffset m_size;
    wxDateTime m_dateTime;
    wxString m_permissions;
    int      m_type;
    int      m_image;
  private:
    void Init();
};

class wxFileCtrl : public wxListCtrl {
  public:
    wxFileCtrl();
    wxFileCtrl( wxWindow *win,
                wxWindowID id,
                const wxString &wild,
                bool showHidden,
                const wxPoint &pos = wxDefaultPosition,
                const wxSize &size = wxDefaultSize,
                long style = wxLC_LIST,
                const wxValidator &validator = wxDefaultValidator,
                const wxString &name = wxT( "filelist" ) );
    virtual ~wxFileCtrl();

    virtual void ChangeToListMode();
    virtual void ChangeToReportMode();
    virtual void ChangeToSmallIconMode();
    virtual void ShowHidden( bool show = true );
    bool GetShowHidden() const { return m_showHidden; }

    virtual long Add( wxFileData *fd, wxListItem &item );
    virtual void UpdateItem( const wxListItem &item );
    virtual void UpdateFiles();
    virtual void MakeDir();
    virtual void GoToParentDir();
    virtual void GoToHomeDir();
    virtual void GoToDir( const wxString &dir );
    virtual void SetWild( const wxString &wild );
    wxString GetWild() const { return m_wild; }
    wxString GetDir() const { return m_dirName; }

    void OnListDeleteItem( wxListEvent &event );
    void OnListDeleteAllItems( wxListEvent &event );
    void OnListEndLabelEdit( wxListEvent &event );
    void OnListColClick( wxListEvent &event );

    virtual void SortItems( wxFileData::fileListFieldType field, bool foward );
    bool GetSortDirection() const { return m_sort_foward; }
    wxFileData::fileListFieldType GetSortField() const { return m_sort_field; }

  protected:
    void FreeItemData( wxListItem& item );
    void FreeAllItemsData();

    wxString      m_dirName;
    bool          m_showHidden;
    wxString      m_wild;

    bool m_sort_foward;
    wxFileData::fileListFieldType m_sort_field;

  private:
    DECLARE_DYNAMIC_CLASS( wxFileCtrl )
    DECLARE_EVENT_TABLE()
};

#endif // _WX_FILEDLGG_H_
